package com.xujl.task;

import com.xujl.task.consts.TaskRetry;
import com.xujl.task.consts.TaskType;
import com.xujl.task.delegate.AbstractTaskDelegate;
import com.xujl.task.delegate.NormalTaskDelegate;

import java.util.Observable;
import java.util.concurrent.Future;

public abstract class Task<T> extends Observable implements RxLife {
    /**
     * 任务状态：默认，运行中，已销毁
     */
    public static final String STATE_DEFAULT = "default";
    public static final String STATE_RUNNING = "running";
    public static final String STATE_DESTROY = "destroy";
    private static final String TAG = "Task";
    private AbstractTaskDelegate<T> mDelegate;
    /**
     * 任务类型
     */
    @TaskType.Enum
    private int mTaskType;
    /**
     * 任务编号
     */
    protected String taskId;

    public Task () {
        this(false, TaskType.TYPE_NORMAL);
    }

    public Task (boolean needCancel) {
        this(needCancel, TaskType.TYPE_NORMAL);
    }

    public Task (TaskBuilder builder) {
        this(builder.isNeedCancel(), builder.getTaskType(), builder.getRetryMaxCount());
    }

    public Task (boolean needCancel, @TaskType.Enum int type) {
        this(needCancel, type, TaskRetry.NONE);
    }

    public Task (boolean needCancel, @TaskType.Enum int type, int retryMaxCount) {
        mTaskType = type;
        if (type == TaskType.TYPE_NORMAL) {
            mDelegate = new NormalTaskDelegate<>(this, needCancel);
            mDelegate.setRetryMaxCount(retryMaxCount);
        }
    }


    public void run (Emitter<T> emitter) throws Exception {

    }

    /**
     * 生命周期结束后，子线程任务依然会执行
     * 完毕，但不会再回调结果,如果需要及时停止
     * 子线程任务，请在子线程任务中根据方法isDestroy()
     * 加以判断
     */
    public void onDestroy () {
        mDelegate.onDestroy();
    }

    @Override
    public void doUnbind () {
        mDelegate.doUnbind();
    }

    @Override
    public boolean isDestroy () {
        return mDelegate.isDestroy();
    }

    /**
     * 仅仅执行ui任务，
     * 主线程回调
     */
    public void onlyRunUiTask () {

    }

    /**
     * 当前线程回调，取决于开启任务的线程
     *
     * @param rxLife
     * @return 是否强绑定Emitter, 强绑定状态下，任务完成不会自动
     * 解除handler关联
     */
    public boolean bindLife (RxLife rxLife) {
        return false;
    }

    /**
     * 主线程回调
     *
     * @param data
     */
    public void onNext (T data) {

    }

    /**
     * @param code 识别码
     * @param obj
     */
    public void onObjNext (int code, Object obj) {

    }

    /**
     * 主线程回调
     *
     * @param e
     */
    public void onError (Exception e) {
        mDelegate.onError(e);
    }

    /**
     * 主线程回调
     */
    public void onFinished () {
        mDelegate.onFinished();
    }

    /**
     * 取消任务
     * 只能是停掉线程中有sleep,wait,join逻辑的线程，抛出一个InterruptException
     *
     * @param interrupt
     * @return
     */
    public boolean cancel (boolean interrupt) {
        return mDelegate.cancel(interrupt);
    }

    public void reset () {
        mDelegate.reset();
    }

    public Future<T> getFuture () {
        return mDelegate.getFuture();
    }

    public void setFuture (Future<T> future) {
        mDelegate.setFuture(future);
    }

    public boolean isNeedCancel () {
        return mDelegate.isNeedCancel();
    }

    public void setNeedCancel (boolean needCancel) {
        mDelegate.setNeedCancel(needCancel);
    }


    Emitter getEmitter () {
        return mDelegate.getEmitter();
    }

    @Override
    public boolean equals (Object obj) {
        return super.equals(obj);
    }

    @Override
    public int hashCode () {
        return super.hashCode();
    }

    public String getTaskId () {
        return taskId;
    }


    public int getTaskType () {
        return mTaskType;
    }

    public AbstractTaskDelegate<T> getDelegate () {
        return mDelegate;
    }

    public int getRetryMaxCount () {
        return mDelegate.getRetryMaxCount();
    }

    public void setRetryMaxCount (int retryMaxCount) {
        mDelegate.setRetryMaxCount(retryMaxCount);
    }

    /**
     * 任务是否还可以重试
     *
     * @return
     */
    public boolean canRetry () {
        return mDelegate.canRetry();
    }

    /**
     * 获取当前重试次数
     *
     * @return
     */
    public int getRetryCount () {
        return mDelegate.getRetryCount();
    }


    @Override
    protected void finalize () throws Throwable {
        RxLog.d(TAG, taskId + ":即将被回收");
        super.finalize();
    }

    void setDestroy (boolean destroy) {
        mDelegate.setDestroy(destroy);
    }


    public String getTaskState () {
        return mDelegate.getTaskState();
    }

    void setTaskState (String taskState) {
        mDelegate.setTaskState(taskState);
        setChanged();
    }

    public void recycle () {
        mDelegate = null;
    }

    public void setTaskId (String taskId) {
        this.taskId = taskId;
    }
}
